package com.net.io;

/**
 * 
 * AIO: 同步阻塞   阻塞整个步骤
 * NIO: 同步非阻塞（多路复用） 阻塞业务处理但不阻塞数据接收
 * AIO: 异步非阻塞
 * 
 * 
 * 同步与异步（面向连接请求、不需要等待处理结果）
 * 同步： 同步就是发起一个调用后，被调用者 未处理完请求 之前，调用不返回。
 * 异步： 异步就是发起一个调用后，立刻得到被调用者的回应表示 已接收到请求，但是被调用者 并没有返回结果，此时我们可以处理其他的请求，被调用者通常依靠事件，回调等机制来通知调用者其返回结果。
 * 同步和异步的区别最大在于异步的话调用者不需要等待处理结果，被调用者会通过回调等机制来通知调用者其返回结果。
 *
 * 阻塞和非阻塞（面向请求处理结果）
 * 阻塞： 阻塞就是发起一个请求，调用者一直等待请求结果返回，也就是当前线程会被挂起，无法从事其他任务，只有当条件就绪才能继续。
 * 非阻塞： 非阻塞就是发起一个请求，调用者不用一直等着结果返回，可以先去干其他事情。
 * 
 * 
 * @author zhangtengfei
 * @date 2021/7/30 10:31
 */


public class IoDescription {
    /**
     为什么Netty使用NIO而不是AIO？
     在Linux系统上，AIO的底层实现仍使用Epoll，没有很好实现AIO，因此在性能上没有明显的优势，而且被JDK封装了一层不容易深度优化，Linux上AIO还不够成熟。
     Netty是异步非阻塞框架，Netty在NIO上做了很多异步的封装。

     同步异步与阻塞非阻塞(段子)
     老张爱喝茶，废话不说，煮开水。
     出场人物：老张，水壶两把（普通水壶，简称水壶；会响的水壶，简称响水壶）。
     1 老张把水壶放到火上，立等水开。（同步阻塞）
     老张觉得自己有点傻
     2 老张把水壶放到火上，去客厅看电视，时不时去厨房看看水开没有。（同步非阻塞）
     老张还是觉得自己有点傻，于是变高端了，买了把会响笛的那种水壶。水开之后，能大声发出嘀~~~~的噪音。
     3 老张把响水壶放到火上，立等水开。（异步阻塞）
     老张觉得这样傻等意义不大
     4 老张把响水壶放到火上，去客厅看电视，水壶响之前不再去看它了，响了再去拿壶。（异步非阻塞）
     老张觉得自己聪明了。

     所谓同步异步，只是对于水壶而言。
     普通水壶，同步；响水壶，异步。
     虽然都能干活，但响水壶可以在自己完工之后，提示老张水开了。这是普通水壶所不能及的。
     同步只能让调用者去轮询自己（情况2中），造成老张效率的低下。
     所谓阻塞非阻塞，仅仅对于老张而言。
     立等的老张，阻塞；看电视的老张，非阻塞。


     BIO是同步阻塞IO，NIO是同步非阻塞IO，AIO是异步非阻塞IO；
     BIO是一个客户端对应一个线程，优化的话可以用线程池进行线程复用，但本质还是一个客户端-服务端通信对应一个线程；
     NIO只需要一个线程负责多路复用器selector的轮询，就可以处理不同客户端channel中的读/写事件，所以多个客户端实际只对应一个线程，另外服务器端和客户端均使用缓冲区的方式进行读写；
     AIO不需要过多的多路服务器selector即可实现异步读写

     当一个连接建立之后，他有两个步骤要做，第一步是接收完客户端发过来的全部数据，第二步是服务端处理完请求业务之后返回response给客户端。NIO和BIO的区别主要是在第一步。
     在BIO中，等待客户端发数据这个过程是阻塞的，这样就造成了一个线程只能处理一个请求的情况，而机器能支持的最大线程数是有限的，这就是为什么BIO不能支持高并发的原因。
     而NIO中，当一个Socket建立好之后，Thread并不会阻塞去接受这个Socket，而是将这个请求交给Selector，Selector会不断的去遍历所有的Socket，一旦有一个Socket建立完成，他会通知Thread，然后Thread处理完数据再返回给客户端——这个过程是不阻塞的，这样就能让一个Thread处理更多的请求了。


     IO，同步阻塞IO，阻塞整个步骤，如果连接少，他的延迟是最低的，因为一个线程只处理一个连接，适用于少连接且延迟低的场景，比如说数据库连接。
     NIO，同步非阻塞IO，阻塞业务处理但不阻塞数据接收，适用于高并发且处理简单的场景，比如聊天软件。
     多路复用IO，他的两个步骤处理是分开的，也就是说，一个连接可能他的数据接收是线程a完成的，数据处理是线程b完成的，他比BIO能处理更多请求。
     信号驱动IO，这种IO模型主要用在嵌入式开发，不参与讨论。
     异步IO，他的数据请求和数据处理都是异步的，数据请求一次返回一次，适用于长连接的业务场景。
     
     */
}
